﻿/******************************************************************************
* SunnyUI.FrameDecoder 开源TCP、串口数据解码库。
* CopyRight (C) 2022-2023 ShenYongHua(沈永华).
* QQ群：56829229 QQ：17612584 EMail：SunnyUI@qq.com
*
* Blog:   https://www.cnblogs.com/yhuse
* Gitee:  https://gitee.com/yhuse/SunnyUI.FrameDecoder
*
* SunnyUI.FrameDecoder.dll can be used for free under the MIT license.
* If you use this code, please keep this note.
* 如果您使用此代码，请保留此说明。
******************************************************************************
* 文件名称: LineBasedFrameDecoder.cs
* 文件说明: 基于换行符 - 数据帧解码器
* 当前版本: V1.0
* 创建日期: 2022-11-01
*
* 2022-11-01: V1.0.0 增加文件说明
******************************************************************************/

using System;

namespace Sunny.FrameDecoder
{
    /// <summary>
    /// 基于换行符 - 数据帧解码器
    /// </summary>
    public class LineBasedFrameDecoder : BaseStringFrameDecoder
    {
        readonly char[] returnChar = new char[] { '\r' };

        /// <summary>
        /// 解码函数
        /// </summary>
        protected override void Decoding()
        {
            int idx = Cache.WrittenSpan.IndexOf(returnChar.AsSpan());
            while (idx >= 0)
            {
                LastDecodedTime = DateTime.Now;
                StringFrameEventArgs e = new StringFrameEventArgs(this, Cache.WrittenSpan.Slice(0, idx).ToString());
                InvokeOnDecoder(e);

                Cache.Remove(idx);
                while (Cache.WrittenCount > 0 && Cache.WrittenSpan.Slice(0, 1).SequenceEqual(returnChar.AsSpan()))
                {
                    Cache.Remove(1);
                }

                if (Cache.WrittenCount == 0) break;
                idx = Cache.WrittenSpan.IndexOf(returnChar.AsSpan());
            }
        }

        /// <summary>
        /// 准备数据解码
        /// </summary>
        /// <param name="data">输入数据</param>
        /// <returns>判断此数据是否可以解码</returns>
        protected override bool PrepareDecode(ref string data)
        {
            if (data == null || data.Length == 0)
            {
                InvokeDecoderError("The data to be decoded is null.", data);
                return false;
            }

            data = data.Replace('\n', '\r');

            return true;
        }
    }
}
